#include <Lucnx/interrupt.h>
#include <Lucnx/debug.h>
#include <Lucnx/list.h>

void list_init(list *p_list)
{
    bool old_state = set_interrupt_state(false);
    p_list->head.next = &p_list->tail;
    p_list->head.prev = NULL;
    p_list->tail.next = NULL;
    p_list->tail.prev = &p_list->head;
    set_interrupt_state(old_state);
}

void list_inside(list_node *before, list_node *node)
{
    bool old_state = set_interrupt_state(false);
    before->prev->next = node;
    node->prev = before->prev;
    before->prev = node;
    node->next = before;
    set_interrupt_state(old_state);
}

void list_remove(list_node *node)
{
    bool old_state = set_interrupt_state(false);
    node->prev->next = node->next;
    node->next->prev = node->prev;
    set_interrupt_state(old_state);
}

list_node *list_pop(list *p_list)
{
    list *list_node = p_list->head.next;
    if (list_node == &p_list->tail)
    {
        return NULL;
    }
    list_remove(list_node);
    return list_node;
}

void list_push(list *p_list, list *node)
{
    list_inside(p_list->head.next, node);
}

void list_add_end(list *p_list, list_node *node)
{
    list_remove(node);
    list_inside(&p_list->tail, node);
}

bool list_find(list *p_list, list_node *node)
{
    for ( list_node *ptr = &p_list->head.next; ptr != &p_list->tail; ptr = ptr->next)
    {
        if (ptr == node)
        {
            return true;
        }
    }
    return false;
}

bool list_null(list *p_list)
{
    if (p_list->head.next == &p_list->tail)
    {
        return true;
    }
    return false;
}